package life.system.auth.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.alibaba.fastjson.TypeReference;
import life.system.auth.feign.MemberFeignService;
import life.system.auth.service.WechatService;
import life.system.auth.utils.HttpClientUtils;
import life.system.auth.vo.RawDataDO;
import life.system.auth.vo.WechatLoginRequest;
import life.system.common.dto.MemberResponseVo;
import life.system.common.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


@Service
public class WechatServiceImpl implements WechatService {

    @Autowired
    private MemberFeignService memberFeignService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String appid = "wx11f0faeadea2786f";
    private static final String secret = "4ed6ffdd9082cd091ce796c7417fce22";
    private static final String request_url = "https://api.weixin.qq.com/sns/jscode2session";
    private static final String grant_type = "authorization_code";


    @Transactional
    public Map<String, Object> getUserInfoMap(WechatLoginRequest loginRequest) throws Exception {
        Map<String, Object> userInfoMap = new HashMap<>();
        JSONObject sessionKeyOpenId = getSessionKeyOrOpenId(loginRequest.getCode());

        // 获取openId && sessionKey
        String openId = sessionKeyOpenId.getString("openid");
        String sessionKey = sessionKeyOpenId.getString("session_key");
        MemberResponseVo insertOrUpdateDO = buildWechatUserAuthInfoDO(loginRequest, sessionKey, openId);

        // 根据openid查询用户，这里的查询service自己写，就不贴出来了
        R member = memberFeignService.getMemberByOpenId(openId);
        if (member.getCode() == 0) {
            MemberResponseVo result = member.getData("member", new TypeReference<MemberResponseVo>() {
            });
            if (result == null) {
                memberFeignService.save(insertOrUpdateDO);
            } else {
                insertOrUpdateDO.setId(result.getId());
                // 已存在，做已存在的处理，如更新用户的头像，昵称等，根据openID更新，这里代码自己写
                memberFeignService.updateByOpenId(insertOrUpdateDO);
            }
            String token = getToken();
            redisTemplate.boundHashOps("token:"+token).put(token,JSON.toJSONString(result));
            userInfoMap.put("token", token);
        }
        return userInfoMap;
    }

    // 这里的JSONObject是阿里的fastjson，自行maven导入
    private JSONObject getSessionKeyOrOpenId(String code) throws Exception {
        Map<String, String> requestUrlParam = new HashMap<>();
        // 小程序appId，自己补充
        requestUrlParam.put("appid", appid);
        // 小程序secret，自己补充
        requestUrlParam.put("secret", secret);
        // 小程序端返回的code
        requestUrlParam.put("js_code", code);
        // 默认参数
        requestUrlParam.put("grant_type", grant_type);

        // 发送post请求读取调用微信接口获取openid用户唯一标识
        String result = HttpClientUtils.doPost(request_url, requestUrlParam);
        return JSON.parseObject(result);
    }

    private MemberResponseVo buildWechatUserAuthInfoDO(WechatLoginRequest loginRequest, String sessionKey, String openId) {
        MemberResponseVo wechatUserDO = new MemberResponseVo();
        wechatUserDO.setOpenId(openId);

        if (loginRequest.getRawData() != null) {
            RawDataDO rawDataDO = JSON.parseObject(loginRequest.getRawData(), RawDataDO.class);
            wechatUserDO.setNickname(rawDataDO.getNickName());
            wechatUserDO.setAvatarUrl(rawDataDO.getAvatarUrl());
            wechatUserDO.setGender(rawDataDO.getGender());
        }

        return wechatUserDO;
    }

    private String getToken() {
        return UUID.randomUUID().toString().replaceAll("-", "")
                .substring(0, 32);
    }
}
